﻿using Consul;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using WesleyRedis;

namespace ConsulRegister
{
    /// <summary>
    /// gRPC服务发现
    /// </summary>
    public static class GrpcServiceConsulExtension
    {
        public static string ConsulAddress = "http://localhost:8500";

        /// <summary>
        /// 获取服务列表
        /// </summary>
        /// <param name="queryOptions"></param>
        /// <param name="serviceName"></param>
        /// <param name="isHttps"></param>
        /// <returns></returns>
        public static Task GetServices(QueryOptions queryOptions, string serviceName, bool isHttps)
        {
            var consulClient = new ConsulClient(c => { c.Address = new Uri(ConsulAddress); });
            var services = consulClient.Health.Service(serviceName, string.Empty, true, queryOptions).Result;
            ////版本号不一致 说明服务列表发生了变化
            if (services.LastIndex != queryOptions.WaitIndex)
            {
                var list = new List<string>();
                var http = isHttps ? "https" : "http";
                foreach (var item in services.Response)
                {
                    list.Add($"{http}://{item.Service.Address}:{item.Service.Port}");
                }
                RedisClient.RedisCt.SetStringKey(serviceName, list, TimeSpan.FromMinutes(60));
            }
            Console.WriteLine($"queryOptions:{services.LastIndex }");
            return null;
        }

        /// <summary>
        /// 获取服务列表
        /// </summary>
        /// <param name="queryOptions"></param>
        /// <param name="serviceName"></param>
        /// <param name="isHttps"></param>
        /// <returns></returns>
        public static Task GetServices(string serviceName, bool isHttps)
        {
            var consulClient = new ConsulClient(c => { c.Address = new Uri(ConsulAddress); });
            var services = consulClient.Health.Service(serviceName, string.Empty, true).Result;
            if (services.Response == null || services.Response.Length == 0)
            {
                throw new Exception($"未发现服务 {serviceName}");
            }
            var list = new List<string>();
            var http = isHttps ? "https" : "http";
            foreach (var item in services.Response)
            {
                list.Add($"{http}://{item.Service.Address}:{item.Service.Port}");
            }
            RedisClient.RedisCt.SetStringKey(serviceName, list, TimeSpan.FromMinutes(60));
            return null;
        }

        /// <summary>
        /// gRPC服务发现
        /// </summary>
        /// <param name="serviceName"></param>
        /// <param name="isHttps"></param>
        /// <returns></returns>
        public static string GetGrpcService(string serviceName, bool isHttps)
        {
            //优先从redis里获取
            var list = RedisClient.RedisCt.GetStringKey<List<string>>(serviceName);
            if (list == null || list.Count == 0)
            {
                GetServices(serviceName, isHttps);
                list = RedisClient.RedisCt.GetStringKey<List<string>>(serviceName);
            }

            return list[new Random().Next(0, list.Count - 1)];
        }
    }
}